#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Create your views here.
import json
from django.http import JsonResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
import pymongo

from application.settings import mongo_cli
from vehicle.consts import RedisKey
from vehicle.models import VehicleInfoModel, VehicleFaultInfoModel, VehicleFaultLogModel, VehicleFenceModel, VehicleMoveInfoModel
from vehicle.serializers import (
    VehicleInfoModelSerializer, VehicleInfoModelCreateUpdateSerializer, 
    VehicleFaultInfoModelSerializer, VehicleFaultInfoModelCreateUpdateSerializer,
    VehicleFaultLogModelSerializer, VehicleFaultLogModelCreateUpdateSerializer,
    VehicleFenceModelSerializer, VehicleFenceModelCreateUpdateSerializer,
    VehicleMoveInfoModelSerializer, VehicleMoveInfoModelCreateUpdateSerializer

)
from vehicle.dal import VehicleDal
from dvadmin.utils.viewset import CustomModelViewSet
from application.settings import redis_cli
from vehicle.consts import VEHICLE_DATA_DICT


class VehicleInfoModelViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = VehicleInfoModel.objects.all()
    serializer_class = VehicleInfoModelSerializer
    create_serializer_class = VehicleInfoModelCreateUpdateSerializer
    update_serializer_class = VehicleInfoModelCreateUpdateSerializer
    filter_fields = ['vehicle_type', 'vehicle_status', 'vehicle_motor', 'vehicle_battery']
    search_fields = ['vin']


class VehicleFaultInfoModelViewSet(CustomModelViewSet):
    """
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """
    queryset = VehicleFaultInfoModel.objects.all()
    serializer_class = VehicleFaultInfoModelSerializer
    create_serializer_class = VehicleFaultInfoModelCreateUpdateSerializer
    update_serializer_class = VehicleFaultInfoModelCreateUpdateSerializer
    filter_fields = ['fault_type', 'fault_group']
    search_fields = ['fault_label', 'fault_code']


class VehicleFaultLogModelViewSet(CustomModelViewSet):
    queryset = VehicleFaultLogModel.objects.all()
    serializer_class = VehicleFaultLogModelSerializer
    create_serializer_class = VehicleFaultLogModelCreateUpdateSerializer
    update_serializer_class = VehicleFaultLogModelCreateUpdateSerializer
    search_fields = ['fault_code', 'vin']


class VehicleFenceModelViewSet(CustomModelViewSet):
    queryset = VehicleFenceModel.objects.all()
    serializer_class = VehicleFenceModelSerializer
    create_serializer_class = VehicleFenceModelCreateUpdateSerializer
    update_serializer_class = VehicleFenceModelCreateUpdateSerializer
    search_fields = ['fence_name']


class VehicleMoveInfoModelViewSet(CustomModelViewSet):
    queryset = VehicleMoveInfoModel.objects.all()
    serializer_class = VehicleMoveInfoModelSerializer
    create_serializer_class = VehicleMoveInfoModelCreateUpdateSerializer
    update_serializer_class = VehicleMoveInfoModelCreateUpdateSerializer
    search_fields = ['vehicle_vin']


class VehicleInfoRealDataView(View):
    """获取实时数据"""
    def get(self, request, vin):
        common_keys = (
            "latitude", "longitude", "speed", "voltage",
            "singleBatteryMinTemperature")
        data = redis_cli.rpop(vin)
        real_info = dict()
        if data:
            real_info = json.loads(data)
            common_info = {k: v for k, v in real_info.items() if k in common_keys}
            real_info = {v: real_info.get(k) for k, v in VEHICLE_DATA_DICT.items()}
            real_info.update(common_info)
        return JsonResponse(dict(code=2000, data=real_info))


class VehicleInfoHistoryDataView(View):
    """获取历史数据"""
    def get(self, request, vin):
        common_keys = (
            "latitude", "longitude", "speed", "voltage",
            "singleBatteryMinTemperature")
        data = redis_cli.rpop(RedisKey.get_history_move_key(vin))
        real_info = dict()
        if data:
            real_info = json.loads(data)
            common_info = {k: v for k, v in real_info.items() if k in common_keys}
            real_info = {v: real_info.get(k) for k, v in VEHICLE_DATA_DICT.items()}
            real_info.update(common_info)
        return JsonResponse(dict(code=2000, data=real_info))


@method_decorator(csrf_exempt, name='dispatch')
class VehicleMovePathStartView(View):
    def post(self, request):
        """根据move_id将mongo中的数据取出放到redis队列中供前端渲染历史轨迹"""
        data = json.loads(request.body)
        move_id = data.get('move_id')
        vin = data.get('vin')
        vehicle_data_coll = mongo_cli.vehicle.vehicle_data
        datas = vehicle_data_coll.find({"uid": move_id}).sort("timestamp", pymongo.ASCENDING)
        history_datas = []
        for d in datas:
            d.pop('_id')
            history_datas.append(json.dumps(d))
        if history_datas:
            redis_cli.lpush(RedisKey.get_history_move_key(vin), *history_datas)
        return JsonResponse(dict(code=2000))


class VehicleInfoIndexDataView(View):

    def get(self, request):
        index_data = dict()
        vehicle_dal = VehicleDal()
        vehicle_sum = vehicle_dal.get_vehicle_count()
        vehicle_online_sum = vehicle_dal.get_vehicle_online_count()
        mileage = vehicle_dal.get_mileage()

        vehicle_data = self.get_online_vehicle_data()
        index_data['vehicle_sum'] = vehicle_sum
        index_data['vehicle_online_sum'] = vehicle_online_sum
        index_data['vehicle_datas'] = vehicle_data
        index_data.update(mileage)
        return JsonResponse(dict(code=2000, data=index_data))

    def get_online_vehicle_data(self):
        keys = redis_cli.keys(RedisKey.location + '*')
        vehicle_datas = []
        for key in keys:
            key = key.decode()
            vehicle_data = dict()
            vin = key.replace(RedisKey.location + ':', '')
            position = redis_cli.get(RedisKey.get_location_vin(vin))
            vehicle_data['vin'] = vin
            vehicle_data['position'] = position.decode().split(',')
            vehicle_datas.append(vehicle_data)
        return vehicle_datas
